#include "k2l.h"

static k2l_char stgstm_getchar(k2l_sexp_ref self)
{
	return STGSTM_POS(self) >= strlen(STRING_HEAD(STGSTM_SRC(self)))?
		-1: STRING_HEAD(STGSTM_SRC(self))[STGSTM_POS(self)++];
}

static void stgstm_reset(k2l_sexp_ref self)
{
	if (STGSTM_POS(self)>0) STGSTM_POS(self)--;
}

static void del_stgstm(k2l_sexp_ref self)
{
	del_sexp(STGSTM_SRC(self));
	free_sexp(self);
}

k2l_sexp_ref new_string_stream(k2l_char *p)
{
	static k2l_stream_ops ops = {{del_stgstm, NULL}, stgstm_getchar, stgstm_reset, NULL};
	k2l_sexp_ref r = new_sexp(sizeof(k2l_string_stream_t), SOBJ_TYPE_STREAM, &ops.suqer);
	STGSTM_SRC(r) = new_string(p);
	return r;
}

static k2l_sexp_ref ___rplaca(k2l_sexp_ref args, k2l_sexp_ref *mvp)
{
	del_sexp(CONS_CAR(CONS_FIRST(args)));
	CONS_CAR(CONS_FIRST(args)) = CONS_SECOND(args);
	sexp_ref_up(CONS_FIRST(args)); sexp_ref_up(CONS_SECOND(args));
	return CONS_FIRST(args);
}

static k2l_sexp_ref ___rplacd(k2l_sexp_ref args, k2l_sexp_ref *mvp)
{
	del_sexp(CONS_CDR(CONS_FIRST(args)));
	CONS_CDR(CONS_FIRST(args)) = CONS_SECOND(args);
	sexp_ref_up(CONS_FIRST(args)); sexp_ref_up(CONS_SECOND(args));
	return CONS_FIRST(args);
}

static k2l_sexp_ref ___symbol_name(k2l_sexp_ref args, k2l_sexp_ref *mvp)
{
	sexp_ref_up(SYMBOL_NAME(CONS_FIRST(args)));
	return SYMBOL_NAME(CONS_FIRST(args));
}
